package com.solidsnake.scala.image

import java.awt.Color
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
import java.io.File

/**
 * Created with IntelliJ IDEA.
 * User: solidsnake
 * Date: 13-11-6
 * Time: 下午2:08
 * To change this template use File | Settings | File Templates.
 */
object ImageManage {
  def main(args : Array[String]) : Unit = {

    val path = System.getProperty("user.dir");
    System.out.println(path);
    val graying = this.graying(path + "/checkcode3.gif")
    ImageIO.write(graying, "bmp", new File(path + "/temp/_graying.bmp"));
    val image = this.changeImages(path + "/temp/_graying.bmp");
    ImageIO.write(image, "bmp", new File(path + "/temp/_0.bmp"));

    val image2 = this.removeNoise(path + "/temp/_0.bmp");
    ImageIO.write(image2, "bmp", new File(path + "/temp/_A.bmp"));

    val bufferedImages = this.separationImage(image2);
    for (i <- 0 to bufferedImages.size - 1 ) {
      val tempImage = bufferedImages(i);
      ImageIO.write(tempImage, "bmp", new File(path + "/temp/_" + i + ".bmp"));
    }



  }


  /**
   * 是否是杂质
   * @param colorCode
   * @return
   */
  def isImpurity(colorCode : Int) : Boolean = {
    val color = new Color(colorCode);
    val sum = color.getRed() + color.getGreen() + color.getBlue();
    if(Math.abs(sum - 174) > 130) { //第一位是高位峰值， 对比的是低位峰值和高位峰值的绝对值差
      return true;
    }
    return false;
  }



  /**
   * 修改图片（使图片编程白底黑字）
   * @param path
   * @return
   */
  def changeImages(path : String) : BufferedImage = {
    val image = ImageIO.read(new File(path));
    return this.changeImages(image)
  }

  /**
   *  修改图片（使图片编程白底黑字）
   * @param image
   * @return
   */
  def changeImages(image : BufferedImage) : BufferedImage = {
    val width = image.getWidth();
    val height = image.getHeight();
    for (x <- 0 to width - 1; y <- 0 to height -1) { // 相当于两个循环嵌套
      if(isImpurity(image.getRGB(x, y))) {
        image.setRGB(x, y, Color.WHITE.getRGB());
      }else {
        image.setRGB(x, y, Color.BLACK.getRGB());
      }
    }
    return image;
  }


  /**
   *  删除噪点
   * @param path
   * @return
   */
  def removeNoise(path : String) : BufferedImage = {
    val image = ImageIO.read(new File(path));
    return this.removeNoise(image)
  }

  /**
   *  删除噪点
   * @param image
   * @return
   */
  def removeNoise(image : BufferedImage) : BufferedImage= {
    val width = image.getWidth();
    val height = image.getHeight();
    for (x <- 0 to width - 1; y <- 0 to height -1) { // 相当于两个循环嵌套
    val color = new Color(image.getRGB(x, y));
      if(color.getRGB == Color.BLACK.getRGB()) {
        // 判断四边是否都为白色，如果是，则说明该像素为噪点
        val borderList =
          image.getRGB(x, if(y == 0) y else y- 1) :: // up
            image.getRGB(x, y + 1) :: // down
            image.getRGB(if(x == 0) x else x- 1, y) :: //left
            image.getRGB(x + 1, y) :: Nil // right
        val isNoise = borderList.filter(v => {
            new Color(v).getRGB() == Color.BLACK.getRGB()
          }).length == 0;
        if (isNoise) {
          image.setRGB(x, y, Color.WHITE.getRGB)
        }
      }
    }
    return image;
  }


  /**
   * 根据宽度截取图片
   * @param image
   * @param width
   * @param height
   * @return
   */
  def splitByWidth(image : BufferedImage, width : Int, height : Int) : List[BufferedImage] = {
    var resultImages = List[BufferedImage]();
    var widthCode : String = "";
    //  纵向扫描
    for (x <- 0 to width -1) {
      var flag = false;
      var y : Int = 0;
      while(!flag && y < height) {
        if(image.getRGB(x, y) == Color.BLACK.getRGB()) {
          flag = true;
        }
        y += 1
      }
      val code = if(flag) "1" else "0"
      widthCode += code
    }
    widthCode.indexOf("1", 0)
    var i = widthCode.indexOf("1", 0)
    do {
      val w = widthCode.indexOf("0", i) - i;
      val sabotage = image.getSubimage(i, 0, w, height);
      resultImages = sabotage :: resultImages;
      i = widthCode.indexOf("1", i + w);
    }
    while(i > 0)
    resultImages
  }

  /**
   * 根据高度截取图片
   * @param tempImages
   * @return
   */
  def splitByHeight(tempImages : List[BufferedImage]) : List[BufferedImage] = {
    var resultImages = List[BufferedImage]();
    for (targetImage <- tempImages) {
      var heightCode : String = "";
      // 横向扫描
      for (y <- 0 to targetImage.getHeight() -1) {
        var flag = false;
        var x : Int = 0;
        while(!flag && x < targetImage.getWidth()) {
          if(targetImage.getRGB(x, y) == Color.BLACK.getRGB()) {
            flag = true;
          }
          x += 1;
        }
        val code = if(flag) "1" else "0"
        heightCode += code
      }

      val x = 0;
      val y = heightCode.indexOf("1");
      val w = targetImage.getWidth();
      val h = heightCode.lastIndexOf("1") - y + 1;
      val sabotage = targetImage.getSubimage(x, y, w, h);
      resultImages = sabotage :: resultImages

    }
    return resultImages;
  }


  /**
     *  灰度化， 这里使用了API的灰度化， 自己使用权重公式，出来的图片是绿色的
     * @param path
     * @return
     */
  def graying(path : String) : BufferedImage = {
    val image = ImageIO.read(new File(path));
    return this.graying(image)
  }

  /**
   *  灰度化， 这里使用了API的灰度化， 自己使用权重公式，出来的图片是绿色的
   * @param image
   * @return
   */
  def graying(image : BufferedImage) : BufferedImage = {
    val grayImage = new BufferedImage(image.getWidth, image.getHeight, BufferedImage.TYPE_BYTE_GRAY)
    for(x  <- 0 to image.getWidth -1; y  <- 0 to image.getHeight - 1) {
      grayImage.setRGB(x, y, image.getRGB(x,y))
    }
    return grayImage
  }


  /**
   * 分割图片
   * @param image
   * @return
   */
  def separationImage(image : BufferedImage) : List[BufferedImage] = {
    var resultImages = List[BufferedImage]();
    val width = image.getWidth();
    val height = image.getHeight();
    val tempImages = this.splitByWidth(image, width, height);
    resultImages = this.splitByHeight(tempImages);
    return resultImages;
  }


  def repairImage(image : BufferedImage) : BufferedImage = {
    def isImpurity(rgb : Int) = rgb == Color.WHITE.getRGB

    def isSign(rgb : Int) = {
      val color = new Color(rgb)
      val flags = (color.getRed <= 10) ::
        (color.getBlue <= 10) ::
        (color.getGreen <= 10) :: Nil
      flags.filter(_ == true).length == 3

    }

    for(x <- 0 to image.getWidth -1; y <- 0 to image.getHeight - 1) {
      if(isImpurity(image.getRGB(x, y))) {
        val borderList =
          image.getRGB(x, if(y == 0) y else y- 1) :: // up
          image.getRGB(x, if(y == image.getHeight - 1) y else y + 1) :: // down
          image.getRGB(if(x == 0) x else x- 1, y) :: //left
          image.getRGB(if(x == image.getWidth - 1) x else x + 1, y) :: Nil // right
        if(borderList.filter(isSign(_)).length >= 3) {
          image.setRGB(x, y, Color.BLACK.getRGB)
        }
      }
    }
    return image
  }


}
